﻿using RXY_Mall.AdminApi.Models;
using RXY_Mall.Core;
using RXY_Mall.Data;
using RXY_Mall.Domain;
using RXY_Mall.Services;
using RXY_Mall.Services.Finance;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Http;
using System.Xml;

namespace RXY_Mall.AdminApi.Controllers
{
    /// <summary>
    /// 第三方支付接口
    /// </summary>
    [RoutePrefix("Payment")]
    public class PaymentController : BaseApiController
    {
        private RXY_MallContext db = new RXY_MallContext();
        private OrderService orderService = new OrderService();
        private FinanceService financeService = new FinanceService();

        /// <summary>
        /// 支付宝支付回调
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [Route("AlipayPayNotify")]
        public string AlipayPayNotify()
        {
            LogHelper.WriteLog("--------支付宝回调开始-----------------");
            try
            {
                string partner = AppConfig.AlipayPartner;
                string _input_charset = "utf-8";

                //*******加密签名程序开始******* 
                Dictionary<string, string> paramsMap = new Dictionary<string, string>();
                NameValueCollection coll = HttpContext.Current.Request.Form;
                String[] requestItem = coll.AllKeys;

                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < requestItem.Length; i++)
                {
                    paramsMap.Add(requestItem[i], HttpContext.Current.Request.Form[requestItem[i]]);
                    sb.Append(requestItem[i]).Append("=").Append(HttpContext.Current.Request.Form[requestItem[i]]).Append("&");
                }
                LogHelper.WriteLog(sb.ToString().TrimEnd('&'));

                bool checkSign = Aop.Api.Util.AlipaySignature.RSACheckV1(paramsMap, AppConfig.AlipayPublicKey, _input_charset, paramsMap["sign_type"], false);
                LogHelper.WriteLog("验证签名：" + checkSign);

                if (checkSign)
                {
                    string trade_status = paramsMap["trade_status"];
                    if (trade_status == "TRADE_SUCCESS")
                    {
                        //获取订单信息
                        string order_no = paramsMap["out_trade_no"]; //商户订单号
                        string trade_no = paramsMap["trade_no"]; //交易号
                        bool result = PayOrderAsync(order_no, trade_no, (int)PayType.Alipay);
                        if (result)
                        {
                            return "success";
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(ex);
            }
            return "failure";
        }

        /// <summary>
        /// APP微信支付回调
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [Route("WeXinPayNotify")]
        public string WeXinPayNotify()
        {
            LogHelper.WriteLog("--------微信回调开始-----------------");
            string result = @"<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[失败]]></return_msg></xml>";
            try
            {
                HttpRequest request = HttpContext.Current.Request;
                WxPayAPI.ResultNotify resultNotify = new WxPayAPI.ResultNotify(request);
                string xml = resultNotify.ProcessNotify2();
                LogHelper.WriteLog(xml);
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.LoadXml(xml);
                if (xmlDoc.FirstChild["return_code"].InnerText == "SUCCESS")
                {
                    string rechargeNo = xmlDoc.FirstChild["out_trade_no"].InnerText;
                    string pay_sn = xmlDoc.FirstChild["transaction_id"].InnerText;
                    bool resultSuccess = PayOrderAsync(rechargeNo, pay_sn, (int)PayType.WeChatApp);
                    if (resultSuccess)
                    {
                        result = @"<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
                        return result;
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(ex);
                result = @"<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[异常处理]]></return_msg></xml>";
            }

            return result;
        }

        /// <summary>
        /// APP微信支付回调
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [Route("WeXinJsPayNotify")]
        public string WeXinJsPayNotify()
        {
            LogHelper.WriteLog("--------微信回调开始-----------------");
            string result = @"<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[失败]]></return_msg></xml>";
            try
            {
                HttpRequest request = HttpContext.Current.Request;
                WxPayJSAPI.ResultNotify resultNotify = new WxPayJSAPI.ResultNotify(request);
                string xml = resultNotify.ProcessNotify2();
                LogHelper.WriteLog(xml);
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.LoadXml(xml);
                if (xmlDoc.FirstChild["return_code"].InnerText == "SUCCESS")
                {
                    string rechargeNo = xmlDoc.FirstChild["out_trade_no"].InnerText;
                    string pay_sn = xmlDoc.FirstChild["transaction_id"].InnerText;
                    bool resultSuccess = PayOrderAsync(rechargeNo, pay_sn, (int)PayType.WeChatApp);
                    if (resultSuccess)
                    {
                        result = @"<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
                        return result;
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(ex);
                result = @"<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[异常处理]]></return_msg></xml>";
            }

            return result;
        }

        private bool PayOrderAsync(string order_no, string pay_no, int pay_type)
        {
            bool result = false;
            var error = "";
            try
            {
                bool flag = db.gw_finance_payments.Any(p => p.pay_no == pay_no);
                if (flag)
                {
                    return result;
                }

                var payment = new gw_finance_payment()
                {
                    add_time = DateTime.Now,
                    order_no = order_no,
                    pay_no = pay_no,
                    pay_type = pay_type,
                    user_id = 0,
                    type = 1,
                };
                db.gw_finance_payments.Add(payment);
                db.SaveChanges();

                #region 会员订单
                if (order_no.StartsWith("M000"))
                {
                    var orderMember = db.gw_order_members.Include(o => o.gw_user).FirstOrDefault(b => b.order_no == order_no);
                    if (orderMember != null && orderMember.status == (int)OrderStatus.Pay)
                    {
                        //判断订单支付
                        if (!orderService.PayMemberOrder(orderMember, pay_no, out error))
                        {
                            return result;
                        }
                        var now = DateTime.Now;
                        if (orderMember.gw_user.grade == (int)UserGrade.Ordinary)
                        {
                            orderMember.gw_user.grade = (int)UserGrade.Member;
                            orderMember.gw_user.start_time = now;
                            orderMember.gw_user.end_time = now.AddYears(orderMember.buy_year);

                            db.Entry(orderMember.gw_user).Property(o => o.grade).IsModified = true;
                            db.Entry(orderMember.gw_user).Property(o => o.start_time).IsModified = true;
                            db.Entry(orderMember.gw_user).Property(o => o.end_time).IsModified = true;
                        }
                        else
                        {
                            //判断是否过期
                            if (orderMember.gw_user.end_time != null && DateTime.Compare((DateTime)orderMember.gw_user.end_time, now) > 0)
                            {
                                var end = ((DateTime)orderMember.gw_user.end_time);
                                orderMember.gw_user.end_time = end.AddYears(orderMember.buy_year);
                            }
                            else
                            {
                                db.Entry(orderMember.gw_user).Property(o => o.grade).IsModified = true;
                                db.Entry(orderMember.gw_user).Property(o => o.start_time).IsModified = true;
                                db.Entry(orderMember.gw_user).Property(o => o.end_time).IsModified = true;
                            }
                        }

                        orderMember.status = (int)OrderStatus.Complete;
                        orderMember.pay_no = pay_no;
                        orderMember.pay_time = DateTime.Now;
                        orderMember.pay_type = pay_type;
                        db.Entry(orderMember).Property(o => o.status).IsModified = true;
                        db.Entry(orderMember).Property(o => o.pay_no).IsModified = true;
                        db.Entry(orderMember).Property(o => o.pay_time).IsModified = true;
                        db.Entry(orderMember).Property(o => o.pay_type).IsModified = true;


                        payment = db.gw_finance_payments.FirstOrDefault(p => p.pay_no == pay_no);
                        payment.user_id = orderMember.user_id;
                        db.Entry(payment).Property(p => p.user_id).IsModified = true;

                        db.SaveChanges();

                        var end_date = DateTime.Parse("2018-10-11");
                        if (end_date > DateTime.Now)
                        {
                            new UserController().AddUserCoupon(new AddUserCouponInput() { user_id = orderMember.user_id, coupon_id = 84, });
                        }

                        result = true;
                    }
                    return result;
                }
                #endregion

                #region 商品订单
                if (order_no.StartsWith("G"))
                {
                    var order = db.gw_orders
                   .Include(o => o.gw_order_goods)
                   .Include(o => o.gw_order_group)
                   .Include(o => o.gw_order_group.gw_order_group_user)
                   .FirstOrDefault(o => o.order_no == order_no);

                    if (order.pay_status == (int)PayStatus.未付款)
                    {
                        //判断订单支付
                        if (!orderService.PayOrder(order, pay_no, out error))
                        {
                            return result;
                        }

                        order.status = (int)OrderStatus.Shipment;

                        order.order_status = (byte)OrderStatus2.处理中;
                        order.pay_no = pay_no;
                        order.pay_time = DateTime.Now;
                        order.pay_type = pay_type;
                        order.pay_status = (byte)PayStatus.已付款;
                        db.Entry(order).Property(o => o.status).IsModified = true;
                        db.Entry(order).Property(o => o.order_status).IsModified = true;
                        db.Entry(order).Property(o => o.pay_no).IsModified = true;
                        db.Entry(order).Property(o => o.pay_time).IsModified = true;
                        db.Entry(order).Property(o => o.pay_type).IsModified = true;
                        db.Entry(order).Property(o => o.pay_status).IsModified = true;

                        #region 订单通知
                        //订单支付通知
                        gw_message messageOrder = new gw_message()
                        {
                            add_time = DateTime.Now,
                            title = "支付成功通知",
                            summary = "上趣加，用余额支付，多省一点！",
                            content = string.Format("订单号：{0}\n商品名称：{1}\n交易时间：{2}\n订单总价:{3}\n订单状态：支付成功", order.order_no, order.gw_order_goods.FirstOrDefault().goods_name, ((DateTime)order.pay_time).ToString("yyyy-MM-dd HH:mm:ss"), order.amount),
                            picture_url = order.gw_order_goods.FirstOrDefault().picture_url,
                            status = 1,
                            type = (int)MessageType.Order,
                            user_id = order.user_id,
                        };
                        gw_message_rule_order messageRuleOrder = new gw_message_rule_order()
                        {
                            order_no = order.order_no,
                            order_status = order.status,
                        };
                        messageOrder.gw_message_rule_order = messageRuleOrder;
                        db.gw_messages.Add(messageOrder);
                        #endregion

                        payment = db.gw_finance_payments.FirstOrDefault(p => p.pay_no == pay_no);
                        payment.user_id = order.user_id;
                        db.Entry(payment).Property(p => p.user_id).IsModified = true;

                        db.SaveChanges();

                        //拆单
                        orderService.SeparateOrder(order.id);
                    }
                }
                #endregion

            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(ex);
            }
            return false;
        }

    }
}
